這系列無障礙的鐵人賽文章,實踐的內容主要是根據 W3C:WAI-ARIA 的實踐,從設計模式及組件(Design Patterns and Widgets)裡面挑選最想嘗試的,如果有朋友想瞭解全部 Widget 該怎麼實作及其規範,歡迎自行爬規範內容,也許我們可以討論一下;若以下文章內容理解有任何錯誤,請多指教~
3.16 Menu Button
A menu button is a button that opens a menu. It is often styled as a typical push button with a downward pointing arrow or triangle to hint that activating the button will display a menu.
前篇的「真・button——按鈕的世界比你想像複雜,別再用 div 刻假按鈕了!」主要介紹了:
<div>
或 <button>
製作按鈕的差異。想再複習的請點前篇文章,今天想介紹按鈕之於漢堡選單的應用,也就是 Menu Button!
(圖片來源:UXPlanet)
如上圖是三條槓或多條槓的呈現,現代應用程式因為導覽列放置的超連結通常都是三到五個起跳,在行動裝置有較小的版面狀況下,常會透過漢堡選單的視覺,固定覆蓋在畫面最上方,引導讓使用者那個位置可以點選,裡面放著網站的導覽超連結。
這裡就不探討漢堡選單的利弊,我們可以知道的是目前大多數使用者的使用習慣已經受應用程式介面影響,當他需要拜訪其他頁面時,直覺會想點擊漢堡選單到達目的地。
上
與 下
,可依選項的順序操作焦點。Menu or Menu bar
(這也是 Widgets 之一)。內容太多了,涉略巢狀的選單行為,請點擊文件查看更多鍵盤操作的說明,這裡有 Element UI 團隊整理的簡中版本。
也許日後找機會整理,做成圖片說明比較合適!
button
,如果不是原生 <button>
,應該要加上 role="button"
。aria-haspopup
屬性,值為 true
或是 menu
,表示按鈕將啟動一個視窗,屬性說明點這裡。aria-expanded
屬性,值設為 true
。選單關閉時,建議直接隱藏 aria-expanded
屬性設定,如果選單在關閉的狀態時,你已經為按鈕加上 aria-expanded
屬性,不打算透過 JavaScript 移除屬性,那麼就把值設為 false
吧。id
,方式是為按鈕加上 aria-control="Menu角色元素的id"
。menu
的角色設定。今天想引用 Bootstrap v4.3 的 Navbar 來看看,CSS 知名框架是怎麼處理 A11Y 的呢?一起檢視 Menu Button
的最佳建議是不是都實現了呢?
希望能做到:
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">我們來看 Bootstrap 4.3 Navbar 的可訪問性</a>
<!-- 1. 按鈕角色、3. 定義按鈕能觸發選單、4. 建立選單與按鈕之間的關聯 -->
<!-- a. 注意細節: aria-label -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<!-- 5. 沒有選單角色 -->
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<!-- b. 注意細節: .sr-only -->
<a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
<a class="nav-item nav-link" href="#">Features</a>
<a class="nav-item nav-link" href="#">Pricing</a>
<!-- c. 注意細節: disabled 的處理 -->
<a class="nav-item nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</div>
</div>
</nav>
button
。aria-haspopup
屬性,值為 true
或是 menu
。aria-expanded
屬性,值設為 true
,反之亦然。id
,方式是為按鈕加上 aria-control="Menu角色元素的id"
。menu
的角色設定。註:此範例不是巢狀選單, menu
角色其餘的行為這裡不檢查。Bootstrap 對於沒加上 role="menu" 的說明:
The WAI ARIA standard defines an actual role="menu" widget, but this is specific to application-like menus which trigger actions or functions. ARIA menus can only contain menu items, checkbox menu items, radio button menu items, radio button groups, and sub-menus. Bootstrap’s dropdowns, on the other hand, are designed to be generic and applicable to a variety of situations and markup structures. For instance, it is possible to create dropdowns that contain additional inputs and form controls, such as search fields or login forms. For this reason, Bootstrap does not expect (nor automatically add) any of the role and aria- attributes required for true ARIA menus. Authors will have to include these more specific attributes themselves.
a. 按鈕本身有加上 aria-label="Toggle navigation"
在 Accessibility Tree 上為自己補充名稱,因為按鈕的內容是「漢堡圖示」 <span class="navbar-toggler-icon"></span>
,所以一定要加上 aria-label
唷!
b. .sr-only
這個樣式是要給螢幕閱讀器讀取的,它消失在瀏覽器的畫面上,卻不是真正的消失。
真正消失是指使用 display: none
或是 visibility: hidden
或是 HTML5 的 hidden
屬性。
不是真正的消失指的作法如下:
<a class="nav-item nav-link active" href="#">Home <span class="sr-only">(current)</span></a>
/* _screen-reader.scss */
.sr-only {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
overflow: hidden;
clip: rect(0,0,0,0);
white-space: nowrap;
border: 0;
}
我可以想到的另外一種做法是:在超連結上使用 aria-current="page"
,表示目前是當前頁面。
<a class="nav-item nav-link active" href="#" aria-current="page">Home</a>
c. disabled 的處理:
tabindex="-1"
,螢幕閱讀器無法 focus 被 disabled
的元素。aria-disabled="true"
,螢幕閱讀器會知道這是一個 disabled
的超連結。<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">我們來看 Bootstrap 4.3 Navbar 的可訪問性</a>
<!-- 1. 按鈕角色、3. 定義按鈕能觸發選單、4. 建立選單與按鈕之間的關聯、加上 aria-haspopup -->
<!-- a. 注意細節: aria-label -->
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation" aria-haspopup="menu">
<span class="navbar-toggler-icon"></span>
</button>
<!-- 5. 選單角色 -->
<div class="collapse navbar-collapse" id="navbarNavAltMarkup" role="menu">
<div class="navbar-nav">
<!-- b. 注意細節: 移除 .sr-only 改成 aria-current -->
<a class="nav-item nav-link active" href="#" aria-current="page">Home</a>
<a class="nav-item nav-link" href="#">Features</a>
<a class="nav-item nav-link" href="#">Pricing</a>
<!-- c. 注意細節: disabled 的處理 -->
<a class="nav-item nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</div>
</div>
</nav>
最後,這裡還是有為選單加上 role="menu"
,因為我看 menu 這個角色的官方定義沒有像 BS 說的只能容納 checkbox、radio 等元件,而且在這個範例中,它就是我的選單呀~所以在此例補充語義會比較完善。
codepen 在這裏,快來使用鍵盤操作看看吧!還想看更多範例嗎?那就參考 WAI-ARIA Practice 1.1 的選單範例吧。